home *** CD-ROM | disk | FTP | other *** search
- unit DrBobPOP;
- interface
- uses
- Classes, ScktComp;
-
- type
- TBPOP3 = class(TComponent)
- public
- constructor Create(AOwner: TComponent); override;
- destructor Destroy; override;
- public
- procedure ReadMail;
- procedure DeleteMessage(Nr: Integer);
- protected
- _Socket: TClientSocket;
- Step,Mess: Integer;
- procedure SocketRead(Sender: TObject; Socket: TCustomWinSocket);
- procedure SocketWrite(Sender: TObject; Socket: TCustomWinSocket);
- private
- fMailServer: String;
- fUser: String;
- fPassword: String;
- fMessages: Integer;
- published
- property MailServer: String read fMailServer write fMailServer;
- property User: String read fUser write fUser;
- property Password: String write fPassword;
- protected
- function GetMessage(Index: Integer): String;
- public
- property Messages: Integer read fMessages;
- property Message[Index: Integer]: String read GetMessage;
- private
- LastSocket: TCustomWinSocket;
- fMessage: Array of String;
- Status: String;
- end;
-
- implementation
- uses
- SysUtils, Forms; { for the Application.ProcessMessages-loop }
-
- const
- St_USER = 1;
- St_PASS = 2;
- St_STAT = 3;
- St_RETR = 4;
- St_QUIT = 5;
-
- const
- CRLF = #13#10;
-
- constructor TBPOP3.Create(AOwner: TComponent);
- begin
- inherited Create(AOwner);
- _Socket := TClientSocket.Create(Self);
- _Socket.Port := 110;
- _Socket.OnRead := SocketRead;
- _Socket.OnWrite := SocketWrite;
- LastSocket := nil;
- Step := 0
- end {Create};
-
- destructor TBPOP3.Destroy;
- begin
- _Socket.OnRead := nil;
- Step := St_QUIT;
- if Assigned(LastSocket) then LastSocket.SendText('QUIT'+ CRLF);
- _Socket.Free;
- _Socket := nil;
- fMessage := nil;
- inherited Destroy
- end {Destroy};
-
- function TBPOP3.GetMessage(Index: Integer): String;
- begin
- if Index < Length(fMessage) then Result := fMessage[Index]
- else Result := ''
- end {GetMessage};
-
- procedure TBPOP3.DeleteMessage(Nr: Integer);
- begin
- Step := St_QUIT;
- if Assigned(LastSocket) then LastSocket.SendText('DELE '+ IntToStr(Nr) + CRLF);
- repeat
- { need to rewrite this using low-level Windows APIs }
- Application.ProcessMessages
- until Step > St_QUIT
- end;
-
- procedure TBPOP3.SocketRead(Sender: TObject; Socket: TCustomWinSocket);
- var
- EOM: Boolean;
- i: Integer;
- begin
- LastSocket := Socket; { talk back ? }
- Status := Socket.ReceiveText;
- EOM := Pos(#13#10'.'#13#10,Status) = Length(Status)-4;
- while (Length(Status) > 0) and (Status[Length(Status)] in [#10,#13]) do
- Delete(Status,Length(Status),1);
- case Step of
- 0: Step := St_USER;
- St_USER: if Pos('-ERR',Status) > 0 then Step := St_QUIT
- else Step := St_PASS;
- St_PASS: if Pos('-ERR',Status) > 0 then Step := St_QUIT
- else Step := St_STAT;
- St_STAT:
- if Pos('+OK',Status) = 1 then
- try
- try
- Delete(Status,1,3);
- while Status[1] = #32 do Delete(Status,1,1);
- Delete(Status,Pos(#32,Status),255);
- fMessages := StrToInt(Status);
- Mess := fMessages;
- if fMessages > 0 then
- begin
- SetLength(fMessage,Mess);
- for i:=Pred(fMessages) downto 0 do fMessage[i] := ''
- end
- except
- fMessages := 0
- end
- finally
- if fMessages <= 0 then Step := St_QUIT { Bye, Bye }
- else
- begin
- Status := '+OK'; { retrieve first message }
- Mess := 1;
- Step := St_RETR
- end
- end;
- St_RETR:
- begin
- fMessage[Pred(Mess)] := fMessage[Pred(Mess)] + Status;
- if EOM then
- begin
- Delete(fMessage[Pred(Mess)],1,Pos(#13#10,fMessage[Pred(Mess)])+1);
- Delete(fMessage[Pred(Mess)],Length(fMessage[Pred(Mess)]),1);
- Inc(Mess); { message is done in "Message" }
- Status := '+OK'
- end;
- if Mess > fMessages then Step := St_QUIT
- end;
- St_QUIT:
- Inc(Step)
- end;
- SocketWrite(Sender, Socket)
- end {SocketRead};
-
- procedure TBPOP3.SocketWrite(Sender: TObject; Socket: TCustomWinSocket);
- var
- Send: String;
- begin
- Send := 'NOOP';
- case Step of
- St_USER: Send := 'USER ' + fUser;
- St_PASS: Send := 'PASS ' + fPassword;
- St_STAT: Send := 'STAT';
- St_RETR: if Status = '+OK' then
- Send := 'RETR ' + IntToStr(Mess);
- St_QUIT: Send := 'NOOP'; // 'QUIT';
- end;
- if (Step in [St_USER..St_QUIT]) and (Send <> 'NOOP') then
- Socket.SendText(Send + CRLF)
- end {SocketWrite};
-
- procedure TBPOP3.ReadMail;
- begin
- Step := 0;
- _Socket.Active := False;
- _Socket.Host := fMailServer;
- _Socket.Open;
- repeat
- { need to rewrite this using low-level Windows APIs }
- Application.ProcessMessages
- until Step >= St_QUIT
- end {ReadMail};
-
- end.
-